package com.hsh.learning.thread;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Created by root on 17-8-1.
 */

@Data
public class Master {

    //任务队列
    protected Queue<Object> workQueue = new ConcurrentLinkedQueue<Object>();
    //Worker进程队列
    protected Map<String, Thread> threadMap = new HashMap<String, Thread>();
    //子任务处理结果集
    protected Map<String, Object> resultMap = new ConcurrentHashMap<String, Object>();

    public Master(Worker worker, int countWorker) {
        worker.setWorkQueue(workQueue);
        worker.setResultMap(resultMap);
        for (int i = 0; i < countWorker; i++) {
            threadMap.put(Integer.toString(i),
                    new Thread(worker, Integer.toString(i)));
        }
    }

    //是否所有的子任务都介绍了
    public boolean isComplete() {
        for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
            if (entry.getValue().getState() != Thread.State.TERMINATED)
                //存在为完成的线程
                return false;
        }
        return true;
    }

    //提交一个子任务
    public void submit(Object job) {
        workQueue.add(job);
    }

    //返回子任务结果集
    public Map<String, Object> getResultMap() {
        return resultMap;
    }

    //执行所有Worker进程，进行处理
    public void execute() {
        for (Map.Entry<String, Thread> entry : threadMap.entrySet()) {
            entry.getValue().start();
        }
    }

    public static class PlusWorker extends Worker { //求立方和
        @Override
        public Object handle(Object input) {
            int i = (Integer) input;
            return i * i * i;
        }
    }

    public static void main(String[] args) {
        //固定使用4个Workde
        Master master = new Master(new PlusWorker(), 4);
        for (int i = 1; i <= 100; i++) //提交100个子任务
            master.submit(i);
        master.execute(); //开始计算

        Map<String, Object> resultMap = master.getResultMap();

        int re = 0;  //最终计算结果保存在此
        //不需要等待所有Worker都执行完即可
        while (true) {
            Set<String> keys = resultMap.keySet();  //开始计算最终结果
            String key = null;
            for (String k : keys) {
                key = k;
                break;
            }
            Integer i = null;
            if (key != null)
                i = (Integer) resultMap.get(key);
            if (i != null)
                re += i; //最终结果
            if (key != null)
                resultMap.remove(key); //移除已被计算过的项目
            if (master.isComplete() && resultMap.size() == 0)
                break;
        }
        System.out.println(re);
    }
}
